package com.kkwrite.regimen.consumer.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;

import com.alibaba.fastjson.JSON;

/**
 * Created by lisha on 2018/7/14 0:23.
 *
 * @author lisha
 */
@WebFilter
public class TokenCheckFilter implements Filter {
    private final Logger logger = LoggerFactory.getLogger(TokenCheckFilter.class);
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        String uri = req.getRequestURI();

        List<String> uncheckUriList = new ArrayList<>();
        uncheckUriList.add("/login/gettoken");
        uncheckUriList.add("/login/checkalive");
        uncheckUriList.add("/order/wxpaynotify");
        uncheckUriList.add("/order/refund/wxpaynotify");
        uncheckUriList.add("/user/shopgetwxqrcode");
        uncheckUriList.add("/oauth/token");

        if (uncheckUriList.contains(uri) || isSwaggerUIResource(uri)) {
            chain.doFilter(request, response);
            return;
        }
        String token = req.getHeader("token");
        if (StringUtils.isBlank(token) || tokenNotAlive(token)) {
            Map<String, String> out = new HashMap<>(6);
            out.put("success", "false");
            out.put("msg", "002");
            out.put("desc", "token invalid");
            HttpServletResponse res = (HttpServletResponse) response;
            res.setContentType("application/json");
            res.setCharacterEncoding("UTF-8");
            JSON.writeJSONString(res.getWriter(), out);
            return;
        }
        chain.doFilter(request, response);
    }

    private boolean isSwaggerUIResource(String uri) {
        return "/swagger-ui.html".equals(uri) || uri.startsWith("/webjars") || "/swagger-resources".equals(uri)
                || "/v2/api-docs".equals(uri) || uri.startsWith("/configuration");
    }

    private boolean tokenNotAlive(String token) {
        long expire;
        try {
            expire = stringRedisTemplate.getExpire(token);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return true;
        }
        /// 小于10s认为token已过期，在业务逻辑处依然需要判断
        /// 尽量将token过期在filter拦截
        return expire <= 10;
    }

    @Override
    public void destroy() {
    }
}
